﻿namespace Devonline.AspNetCore;

/// <summary>
/// 图片缩放选项
/// 可以从分辨率, 或 Request 参数选项构造
/// 支持的参数形式:
/// resolution | r = {Resolution}
/// size | s = {1280x720}
/// width | w = {int}
/// height | h = {int}
/// </summary>
public class ImageResizeOptions
{
    private const char _sizeSpliter = CHAR_x;

    /// <summary>
    /// 默认构造方法
    /// </summary>
    public ImageResizeOptions() { }

    /// <summary>
    /// 从分辨率初始化
    /// </summary>
    /// <param name="resolution"></param>
    public ImageResizeOptions(Resolution resolution)
    {
        Resolution = resolution;
        GetWidthAndHeight();
    }

    /// <summary>
    /// 构造方法
    /// </summary>
    /// <param name="queryOptions"></param>
    public ImageResizeOptions(string queryOptions)
    {
        if (queryOptions.Contains(AppSettings.DEFAULT_URL_INNER_SPLITER))
        {
            //完整的查询选项
            Init(queryOptions.ToKeyValuePairs(AppSettings.DEFAULT_URL_OUTER_SPLITER, AppSettings.DEFAULT_URL_INNER_SPLITER));
        }
        else if (queryOptions.Contains(_sizeSpliter))
        {
            //仅包含尺寸的查询选项
            Size = queryOptions;
            GetResolution();
            GetWidthAndHeight();
        }
        else
        {
            //仅包含分辨率的查询选项
            if (Enum.TryParse<Resolution>(queryOptions, true, out var resolution))
            {
                Resolution = resolution;
                GetWidthAndHeight();
            }
        }
    }

    /// <summary>
    /// 分辨率(eg: fhd|FHD)
    /// </summary>
    [Abbreviation("r")]
    public Resolution? Resolution { get; set; }
    /// <summary>
    /// 尺寸(eg: 1280x720)
    /// </summary>
    [Abbreviation("s")]
    public string? Size { get; set; }
    /// <summary>
    /// 图片宽度(eg: 1280)
    /// </summary>
    [Abbreviation("w")]
    public int Width { get; set; }
    /// <summary>
    /// 图片高度(eg: 720)
    /// </summary>
    [Abbreviation("h")]
    public int Height { get; set; }

    /// <summary>
    /// 根据上下文键值对初始化图片查询选项
    /// </summary>
    /// <param name="keyValuePairs"></param>
    private void Init(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
    {
        if (keyValuePairs is not null && keyValuePairs.Any())
        {
            var type = GetType();

            // 分辨率选项
            var key = nameof(Resolution).ToLowerInvariant();
            var sanitizedKey = type.GetAbbreviation(nameof(Resolution));
            if (keyValuePairs.Any(x => x.Key == key || x.Key == sanitizedKey))
            {
                var resolution = keyValuePairs.FirstOrDefault(x => x.Key == key || x.Key == sanitizedKey).Value;
                if (Enum.TryParse<Resolution>(resolution, true, out var parsedResolution))
                {
                    Resolution = parsedResolution;
                }
                else
                {
                    Resolution = resolution.GetEnumValueByDisplayName<Resolution>();
                }
            }

            // 图片尺寸选项
            key = nameof(Size).ToLowerInvariant();
            sanitizedKey = type.GetAbbreviation(nameof(Size));
            if (keyValuePairs.Any(x => x.Key == key || x.Key == sanitizedKey))
            {
                Size = keyValuePairs.FirstOrDefault(x => x.Key == key || x.Key == sanitizedKey).Value;
            }

            // 宽度选项
            key = nameof(Width).ToLowerInvariant();
            sanitizedKey = type.GetAbbreviation(nameof(Width));
            if (keyValuePairs.Any(x => x.Key == key || x.Key == sanitizedKey))
            {
                var width = keyValuePairs.FirstOrDefault(x => x.Key == key || x.Key == sanitizedKey).Value;
                if (int.TryParse(width, out var parsedWidth))
                {
                    Width = parsedWidth;
                }
            }

            // 高度选项
            key = nameof(Height).ToLowerInvariant();
            sanitizedKey = type.GetAbbreviation(nameof(Height));
            if (keyValuePairs.Any(x => x.Key == key || x.Key == sanitizedKey))
            {
                var height = keyValuePairs.FirstOrDefault(x => x.Key == key || x.Key == sanitizedKey).Value;
                if (int.TryParse(height, out var parsedHeight))
                {
                    Height = parsedHeight;
                }
            }

            if (string.IsNullOrWhiteSpace(Size) && (Width > 0 || Height > 0))
            {
                // 如果 Size 为空但 Width 或 Height 有值，则构建 Size 字符串
                Size = $"{Width}{_sizeSpliter}{Height}";
            }

            if (string.IsNullOrWhiteSpace(Size) && Resolution is not null)
            {
                // 如果 Size 为空但 Resolution 不为空，则尝试从 Resolution 中提取尺寸
                Size = Resolution.Value.GetExplanation();
            }

            if (Resolution is null)
            {
                GetResolution();
            }

            if (Size is null)
            {
                GetSize();
            }

            GetWidthAndHeight();
        }
    }

    /// <summary>
    /// 根据当前的尺寸获取分辨率
    /// </summary>
    /// <returns></returns>
    public Resolution? GetResolution()
    {
        GetSize();

        if (!string.IsNullOrWhiteSpace(Size))
        {
            Resolution = nameof(Resolution).GetEnumValueByAttributeValue<Resolution, ExplanationAttribute, string>(Size);
        }

        return Resolution;
    }
    /// <summary>
    /// 根据当前的分辨率和尺寸获取图片的实际尺寸
    /// </summary>
    public string? GetSize()
    {
        if (Resolution is not null)
        {
            // 如果 Size 为空但 Resolution 不为空，则尝试从 Resolution 中提取尺寸
            Size = Resolution.Value.GetExplanation();
        }

        if ((Width > 0 || Height > 0))
        {
            // 如果 Size 为空但 Width 或 Height 有值，则构建 Size 字符串
            Size = $"{Width}{_sizeSpliter}{Height}";
        }

        return Size;
    }
    /// <summary>
    /// 根据当前的尺寸获取图片的宽度和高度
    /// </summary>
    /// <returns></returns>
    public (int, int) GetWidthAndHeight()
    {
        GetSize();

        if ((Width == 0 || Height == 0) && !string.IsNullOrWhiteSpace(Size) && Size.Contains(_sizeSpliter))
        {
            // 如果 Size 包含 'x'，则尝试解析 Width 和 Height
            var dimensions = Size.Split(_sizeSpliter);
            if (dimensions.Length == 2)
            {
                if (int.TryParse(dimensions[0], out var parsedWidth))
                {
                    Width = parsedWidth;
                }

                if (int.TryParse(dimensions[1], out var parsedHeight))
                {
                    Height = parsedHeight;
                }
            }
        }

        return (Width, Height);
    }
}